package com.xbongbong.pro.service.toolbox.statistic.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.VisibleTypeEnum;
import com.xbongbong.paas.toolbox.pojo.AppPermissionPojo;
import com.xbongbong.paas.toolbox.pojo.ModulePermissionPojo;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.wrap.DepartmentVO;
import com.xbongbong.paas.toolbox.wrap.RoleSimpleVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.statistic.enums.StatisticsTypeEnum;
import com.xbongbong.pro.statistic.pojo.ChartPermissionDetailsPojo;
import com.xbongbong.pro.statistic.pojo.ChartPermissionsPojo;
import com.xbongbong.pro.statistic.pojo.SlaveSourcePojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.model.DepartmentModel;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * @description: 指标权限help
 * @Author: hongxiao
 * @date: 2019-06-12 13:55
 * @since v1.0
 */
@Component
public class ChartPermissionHelp {
    @Resource
    private DepartmentModel departmentModel;
    /**
     * 权限详情判断(可见/可导出)
     * @param permissionDetails 权限详情
     * @param roleVOSet 当前用户角色集合
     * @param depIdIn 当前用户部门set集合
     * @param userId 当前用户ID
     * @return flag true 有权限 false 无权限
     * @author zhouwq
     * @date 2019/5/8 10:14
     */
    public Boolean permissionsDetailsJudge(ChartPermissionDetailsPojo permissionDetails, Set<RoleSimpleVO> roleVOSet,
                                           Set<Long> depIdIn, String userId){
        //权限判断标志
        boolean flag = false;
        if (permissionDetails == null) {
            return false;
        }
        List<DepartmentEntity> dep = permissionDetails.getDep();
        List<Integer> role = permissionDetails.getRole();
        List<String> userIds = permissionDetails.getUser();
        Integer type = permissionDetails.getType();

        //判断role集合中是否存在roleVOSet中的roleID
        Optional<RoleSimpleVO> roleOptional = roleVOSet.stream().filter(roleVO -> role.contains(roleVO.getId())).findFirst();

        boolean depFlag = false;
        for(DepartmentEntity departmentEntity : dep){
            if(depIdIn.contains(departmentEntity.getId())){
                depFlag = true;
            }
        }

        //角色权限判断
        if (roleOptional.isPresent()) {
            flag = true;
        }
        //部门权限判断
        if (depFlag) {
            flag = true;
        }
        //用户权限判断
        if (userIds.contains(userId)) {
            flag = true;
        }

        if(VisibleTypeEnum.NOT_SHOW_ANYONE.getType().equals(type)){
            flag = !flag;
        }
        return flag;
    }

    /**
     * saas模块权限和paas的app权限
     *
     * @param chartEntity 图表
     * @param saasPermissions saas权限
     * @param appMenuMap app权限
     * @return boolean
     * @author 徐俊杰
     * @date 2019/6/13 10:13
     * @since v1.0
     */
    public boolean filterProPermission4Chart(UserVO loginUser,ChartEntity chartEntity, Set<String> saasPermissions, Map<Long, List<Long>> appMenuMap) {
        // 指标类型
        StatisticsTypeEnum statisticsTypeEnum = StatisticsTypeEnum.getByCode(chartEntity.getStatisticsType());
        if (statisticsTypeEnum == StatisticsTypeEnum.SYSTEM_STATISTIC) {
            // saas权限
            List<Integer> refTypes = JsonHelperUtil.parseArray(chartEntity.getRefTypes(), Integer.class);
            Integer businessType = refTypes.size() > 0 ? refTypes.get(0) : XbbRefTypeEnum.UNKNOWN.getCode();
            XbbRefTypeEnum refTypeEnum = XbbRefTypeEnum.getByCode(businessType);
            return !saasPermissions.contains(refTypeEnum.getAlias());
        } else {
            SlaveSourcePojo driverSourcePojo = chartEntity.getDriverSources().toJavaObject(SlaveSourcePojo.class);
            // saas权限
            Integer saasMark = driverSourcePojo.getSaasMark();
            if (saasMark == null) {
                return false;
            }
            if (saasMark.equals(SaasMarkEnum.SAAS.getCode())) {
                XbbRefTypeEnum refTypeEnum = XbbRefTypeEnum.getByCode(driverSourcePojo.getBusinessType());
                ProPermissionAliasEnum proPermissionAliasEnum = ProPermissionAliasEnum.getByAlias(refTypeEnum.getAlias());
                if (null == proPermissionAliasEnum){
                    return false;
                }
                if (saasPermissions.contains(proPermissionAliasEnum.getAlias())){
                    return false;
                }else {
                    return true;
                }
//                return !saasPermissions.contains(refTypeEnum.getAlias());
            } else if (saasMark.equals(SaasMarkEnum.PAAS.getCode())) {
                // 超管特殊处理
                if (loginUser.isAdminOrBoss()){
                    return false;
                }
                // paas权限
                Long appId = driverSourcePojo.getAppId();
                if (!appMenuMap.containsKey(appId)) {
                    return true;
                }
                Long menuId = driverSourcePojo.getMenuId();
                // 权限过虑
                List<Long> moduleIds = appMenuMap.get(appId);
                return !moduleIds.contains(menuId);
            }
        }

        return false;
    }

    /**
     * 图表具体权限
     *
     * @param loginUser 登录员工
     * @param depIdIn 部门
     * @param chartEntity 图表
     * @return boolean
     * @author 徐俊杰
     * @date 2019/6/13 10:17
     * @since v1.0
     */
    public boolean filterPermission4SingleChart(UserVO loginUser, Set<Long> depIdIn, ChartEntity chartEntity) {
        // 超管特殊处理自定义图表能看见，发布的就能看见
        Boolean isAdmin = loginUser.isAdmin();
        if (isAdmin){
            return false;
        }
        // chart指标权限
        JSONObject permissionsObj = chartEntity.getPermissions();
        if (permissionsObj != null && permissionsObj.size() > 0) {
            ChartPermissionsPojo entity = JSONObject.parseObject(permissionsObj.toJSONString(), ChartPermissionsPojo.class);
            // 是否可见
            Integer visibleType = entity.getVisible();
            if (visibleType.equals(BasicConstant.NO_USE)) {
                return true;
            }
            // 是否是高级设置
            Integer visibleAdvanced = entity.getVisibleScopeEnable();
            if (visibleAdvanced == null || BasicConstant.NO_USE.equals(visibleAdvanced)) {
                return false;
            }
            // 高级设置值
            boolean advancedFlag = permissionsDetailsJudge(entity.getVisibleScopeRule(), loginUser.getRoleSet(), depIdIn, loginUser.getUserId());
            return !advancedFlag;
        }

        return true;
    }

    /**
     * app权限
     *
     * @param permissions paas权限
     * @return java.util.Map<java.lang.Long,java.util.List<java.lang.Long>>
     * @author 徐俊杰
     * @date 2019/6/13 10:37
     * @since v1.0
     */
    public Map<Long, List<Long>> getPaasPermissionMap(String permissions) {
        // paas权限
        List<AppPermissionPojo> appPerms;
        try {
            appPerms = JSON.parseArray(permissions, AppPermissionPojo.class);
        } catch (Exception e) {
            appPerms = new ArrayList<>();
        }
        if (appPerms == null) {
            appPerms = new ArrayList<>();
        }
        Map<Long, List<Long>> appMenuMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (appPerms.size() > 0) {
            for (AppPermissionPojo pojo : appPerms) {
                Long appId = pojo.getAppId();
                List<ModulePermissionPojo> modules = pojo.getModules();
                if (modules != null && modules.size() > 0) {
                    List<Long> moduleIds = new ArrayList<>();
                    modules.forEach(item -> {
                        moduleIds.add(item.getId());
                    });
                    appMenuMap.put(appId, moduleIds);
                }
            }
        }
        return appMenuMap;
    }

    /**
     * 获取该员工所在部门及所有下级部门
     *
     * @param userVO 员工信息
     * @return java.util.Set<java.lang.Long>
     * @author 徐俊杰
     * @date 2019/6/13 10:49
     * @since v1.0
     */
    public Set<Long> getAllDeptIds(UserVO userVO) {
        Set<DepartmentVO> departmentVOSet = userVO.getDepSet();
        Set<Long> depIdIn = new HashSet<>();
        departmentVOSet.forEach(departmentVO -> depIdIn.add(departmentVO.getId()));
        // 部门以及所有下级部门
        List<Long> depLists = departmentModel.getSubDepIdList(userVO.getCorpid(), depIdIn, true);
        depIdIn.addAll(depLists);
        return depIdIn;
    }
}
